﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using ScrumTable.Common.Collections;

#endregion


namespace ScrumTable.Config.ElementManagement
{
    /// <summary>
    /// Represents the configuration data object for the scrum table
    /// configuration settings.
    /// </summary>      
    [Serializable] 
    public class ElementConfig
    {

        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        private List<SerializablePair<int, string>> _closedState;
        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        

        /// <summary>
        /// Gets or sets the Config Name
        /// </summary>
        [XmlAttribute]
        public string ConfigName { get; set; }

        /// <summary>
        /// Gets or sets the id of this config
        /// </summary>
        [XmlAttribute]
        public string ProjectId { get; set; }

        /// <summary>
        /// Gets or sets the id of this config
        /// </summary>
        [XmlAttribute]
        public string SchemaName { get; set; }

        
        /// <summary>
        /// Stores the screen setting, change this value only via gui
        /// </summary>
        [XmlArray("StateConfigTask")]
        [XmlArrayItem(Type = typeof(SerializablePair<int, string>), ElementName = "Entry")]
        public List<SerializablePair<int, string>> StateConfigTask { get; set; }

        /// <summary>
        /// Stores the screen setting, change this value only via gui
        /// </summary>
        [XmlArray("StateConfigBug")]
        [XmlArrayItem(Type = typeof(SerializablePair<int, string>), ElementName = "Entry")]
        public List<SerializablePair<int, string>> StateConfigBug { get; set; }

        /// <summary>
        /// Stores the screen setting, change this value only via gui
        /// </summary>
        [XmlArray("StateConfigStory")]
        [XmlArrayItem(Type = typeof(SerializablePair<int, string>), ElementName = "Entry")]
        public List<SerializablePair<int, string>> StateConfigStory { get; set; }


        /// <summary>
        /// Stores the string to a scrumstate id
        /// </summary>
        [XmlArray("StateImages")]
        [XmlArrayItem(Type = typeof(SerializablePair<int, string>), ElementName = "Entry")]
        public List<SerializablePair<int, string>> StateImages { get; set; }


        /// <summary>
        /// Stores the screen setting, change this value only via gui
        /// </summary>
        [XmlArray("TargetConfig")]
        [XmlArrayItem(Type = typeof(TargetConfig), ElementName = "Target")]
        public List<TargetConfig> TargetConfigs { get; set; }

 

        /// <summary>
        /// Gets or sets the the closed state
        /// </summary>
        [XmlIgnore]
        public List<SerializablePair<int, string>> ClosedStateInternal 
        {
            get
            {
                if (ClosedState == null)
                {
                    _closedState = new List<SerializablePair<int, string>>();
                }
                if (_closedState.Count == 0)
                {
                    if (StateConfigStory.Count > 0)
                    {
                        _closedState.Add(StateConfigStory.Last());
                    }
                }
                else if(_closedState.Count > 5)
                {
                    _closedState = _closedState.GroupBy(x=>x.Left).Select(g=>g.First()).ToList();
                }
                return _closedState;
            }
            set { _closedState = value; }
        }


        /// <summary>
        /// Gets or sets the the closed state
        /// </summary>
        [XmlArray("ClosedStates")]
        [XmlArrayItem(Type = typeof(SerializablePair<int, string>), ElementName = "State")]
        public List<SerializablePair<int, string>> ClosedState
        {
            get { return _closedState; }
            set { _closedState = value; }
        }


        /// <summary>
        /// Gets or sets the config for the user story element
        /// </summary>
        [XmlElement]
        public UiElementConfig TaskElement { get; set; }

        /// <summary>
        /// Gets or sets the config for the user story element
        /// </summary>
        [XmlElement]
        public UiElementConfig StoryElement { get; set; }

        /// <summary>
        /// Gets or sets the config for the user story element
        /// </summary>
        [XmlElement]
        public UiElementConfig BugElement { get; set; }

        /// <summary>
        /// Gets or sets the config for the user story element
        /// </summary>
        /// <summary>
        /// Stores the screen setting, change this value only via gui
        /// </summary>
        [XmlArray("Reports")]
        [XmlArrayItem(Type = typeof(ReportConfig), ElementName = "Report")]
        public List<ReportConfig> Reports { get; set; }


        /// <summary>
        /// Gets or sets a list of associated reports to a control
        /// </summary>
        /// <summary>
        /// Stores the report associated to a control, change this value only via gui
        /// </summary>
        [XmlArray("ReportControl")]
        [XmlArrayItem(Type = typeof(SerializablePair<string, string>), ElementName = "Report")]
        public List<SerializablePair<string, string>> ReportControl { get; set; }

        #endregion

        #region Constructors / Destructor

        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>   
        /// 
        /// </summary>
        public ElementConfig()
        {
            TargetConfigs = new List<TargetConfig>();
            StateImages = new List<SerializablePair<int, string>>();
            ReportControl = new List<SerializablePair<string, string>>();
            Reports = new List<ReportConfig>();

            TaskElement = new UiElementConfig("Task");
            TaskElement.Children.Add(new UiElementConfig("Effort") { Children = new List<UiElementBase>() { new UiElementBase("Estimate"), new UiElementBase("RemainingWork"), new UiElementBase("CompletedWork") } });
            TaskElement.Children.Add(new UiElementConfig("State"));
            TaskElement.Children.Add(new UiElementConfig("Priority"));
            TaskElement.MemoFields.Add("Description");

            BugElement = new UiElementConfig("Bug");
            BugElement.Children.Add(new UiElementConfig("Ranking"));
            BugElement.Children.Add(new UiElementConfig("State"));
            BugElement.Children.Add(new UiElementConfig("Severity"));
            BugElement.MemoFields.Add("Description");

            StoryElement = new UiElementConfig("Story");
            StoryElement.Children.Add(new UiElementConfig("Planning") { Children = new List<UiElementBase>() { new UiElementBase("StoryPoints"), new UiElementBase("Ranking") } });
            StoryElement.Children.Add(new UiElementConfig("State"));
            StoryElement.Children.Add(new UiElementConfig("Risk"));
            StoryElement.MemoFields.Add("Description");
            
        }
        
        /// <summary>
        /// Clones this object
        /// </summary>
        /// <returns></returns>
        public ElementConfig Clone()
        {
            return (ElementConfig)MemberwiseClone();
        }
        
        #endregion

        #region Methods

        #endregion

  

    }


      /// <summary>
    /// Represents the configuration data object for the scrum table
    /// UI element configuration settings.
    /// </summary>   
    [Serializable]
    public class UiElementConfig : UiElementBase
    {
        /// <summary>
        /// Gets all fields definded as memos 
        /// </summary>
        public List<string> MemoFields { get; set; }

        /// <summary>
        /// This constructor is used for serialization / deserialization
        /// purposes. DO NOT USE IT FROM YOUR GLOBAL CODE, USE 
        /// UiElementConfig(string) INSTEAD.
        /// </summary>
        public UiElementConfig(): base()
        {
            MemoFields = new List<string>();
        }

        internal UiElementConfig(string name): base(name)
        {
            MemoFields = new List<string>();
        }

    }
    /// <summary>
    /// Represents the configuration data object for the scrum table
    /// UI element configuration settings.
    /// </summary>   
    [Serializable]
    public class UiElementBase 
    {
        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets/sets the name.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Gets the child elements.
        /// </summary>
        public List<UiElementBase> Children { get; set; }

        #endregion

        #region Constructors / Destructor

        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// This constructor is used for serialization / deserialization
        /// purposes. DO NOT USE IT FROM YOUR GLOBAL CODE, USE 
        /// UiElementConfig(string) INSTEAD.
        /// </summary>
        public UiElementBase()
        {
            Children = new List<UiElementBase>();
        }

        internal UiElementBase(string name)
        {
            Name = name;
            Children = new List<UiElementBase>();
        }

        #endregion
    }


    /// <summary>
    /// Represents the configuration data object for the scrum table
    /// Report
    /// </summary>   
    [Serializable]
    public class ReportConfig
    {
        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets/sets the name of the report.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Gets the child elements.
        /// </summary>
        public List<SerializablePair<string,string>> Parameter { get; set; }

        #endregion

        #region Constructors / Destructor

        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// This constructor is used for serialization / deserialization
        /// purposes. DO NOT USE IT FROM YOUR GLOBAL CODE, USE 
        /// UiElementConfig(string) INSTEAD.
        /// </summary>
        public ReportConfig()
        {
            Parameter = new List<SerializablePair<string, string>>();
        }

        internal ReportConfig(string name)
        {
            Name = name;
            Parameter = new List<SerializablePair<string, string>>();
        }

        #endregion
    }
 }
